# 文件名: create_graph.py
import json
from pyvis.network import Network
import os
import webbrowser
import urllib.parse

def build_graph_from_flat_json(json_filepath, output_filename="Reservoir_Carbon_Knowledge_Graph.html"):
    """
    从包含'entities'和'relations'列表的JSON文件读取数据，
    并使用pyvis构建一个可交互的HTML知识图谱。
    """
    # 1. 加载JSON数据
    try:
        with open(json_filepath, 'r', encoding='utf-8') as f:
            graph_data = json.load(f)
    except FileNotFoundError:
        print(f"错误: JSON文件未找到 at '{json_filepath}'")
        return
    except json.JSONDecodeError:
        print(f"错误: '{json_filepath}' 文件内容不是有效的JSON。")
        return

    entities = graph_data.get('entities', [])
    relations = graph_data.get('relations', [])

    if not entities:
        print("错误: JSON文件中未找到'entities'列表。")
        return

    # 2. 初始化网络图
    net = Network(height="90vh", width="100%", bgcolor="#222222", font_color="white", directed=True, notebook=False)

    # 3. 添加节点 (Entities)
    node_type_colors = {
        "核心概念": "#f44336",
        "温室气体": "#ff9800",
        "排放途径": "#4caf50",
        "碳汇过程": "#03a9f4",
        "碳来源": "#9c27b0",
        "评估方法": "#8bc34a",
        "生命周期阶段": "#ffeb3b",
        "地理因素": "#607d8b",
        "水库特征": "#795548",
        "指标": "#e91e63",
        "监测技术": "#00bcd4",
        "计算模型": "#3f51b5",
        "标准/指南": "#673ab7",
        "政策与经济": "#2196f3",
        "研究前沿": "#ff5722",
        "工程因素": "#cddc39"
    }

    for entity in entities:
        node_id = entity['id']
        node_name = entity['name']
        node_type = entity.get('type', '未知类型')
        node_desc = entity.get('description', '无')
        
        # 创建悬停提示信息
        node_title = (
            f"<b>{node_name}</b><br>"
            f"ID: {node_id}<br>"
            f"类型: {node_type}<br>"
            f"描述: {node_desc}"
        )
        
        node_color = node_type_colors.get(node_type, '#9e9e9e')

        net.add_node(node_id, label=node_name, title=node_title, color=node_color, shape='dot', size=15)

    # 4. 添加边 (Relations)
    for relation in relations:
        source_id = relation['source_id']
        target_id = relation['target_id']
        rel_type = relation.get('relation_type', '关联')
        rel_desc = relation.get('description', '')

        # 将关系类型和描述作为边的标题
        edge_title = f"{rel_type}: {rel_desc}"

        net.add_edge(
            source_id, 
            target_id, 
            title=edge_title, 
            label=rel_type, # 在边上显示关系类型
            color={'inherit': 'from'}, 
            arrows='to'
        )

    # 5. 设置物理引擎参数以获得更好的布局
    net.set_options("""
    var options = {
      "nodes": {
        "font": {
          "size": 12
        }
      },
      "edges": {
        "font": {
          "size": 10,
          "align": "top"
        },
        "smooth": {
          "type": "dynamic"
        }
      },
      "physics": {
        "barnesHut": {
          "gravitationalConstant": -20000,
          "centralGravity": 0.1,
          "springLength": 150,
          "springConstant": 0.05
        },
        "solver": "barnesHut",
        "minVelocity": 0.75,
        "stabilization": {
          "iterations": 150
        }
      },
      "interaction": {
        "hover": true,
        "tooltipDelay": 200
      }
    }
    """)

    # 6. 生成HTML文件
    try:
        net.save_graph(output_filename)
        output_path = os.path.abspath(output_filename)
        # 对包含非ASCII字符的路径进行URL编码
        encoded_path = urllib.parse.quote(output_path)
        print(f"\n成功！已生成交互式图谱: {output_path}")
        print("正在尝试在您的默认浏览器中打开...")
        webbrowser.open(f'file://{encoded_path}')
    except Exception as e:
        print(f"生成或打开图谱时发生错误: {e}")

# --- 主程序 ---
if __name__ == "__main__":
    json_file = 'knowledge_graph.json'
    build_graph_from_flat_json(json_file)